import axios from 'axios'
import { Message } from 'element-ui'
import router from '@/router'
import store from '@/store'
import { resetRouter } from '@/router/index'

const request = axios.create({
  // 项目的基地址

  // process.env是webpack的语法 在webpack打包时会找到对应的.env文件
  // 获取到VUE_APP_BASE_URL的值 付给baseURL
  // 什么是环境变量
  // 根据执行命令的不同 会自动匹配对应环境
  // 在此环境下生效的变量 就是环境变量
  // npm run serve 匹配开发环境 development
  // npm run build 匹配生产环境 production
  baseURL: process.env.VUE_APP_BASE_URL, // 环境变量
  // 接口的超时时间
  timeout: 20000 // request timeout
})

// 请求拦截器
// 在请求发起之前执行
// 在headers 上绑定token
request.interceptors.request.use(
  (config) => {
    // console.log(config)
    const token = store.state.user.token
    // 判断 当headers上没有Authorization字段 并且token 有值得情况下给请求头加上token
    if (!config.headers.Authorization && token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 响应拦截器
// 在请求响应之后执行
// 对请求回来的结果进行处理
// 正确的结果 直接返回
// 错误的结果 状态码不同有不同的处理
// 如果不做处理的话 network 可能显示false或者 但是你还是登录成功了
request.interceptors.response.use(
  (response) => {
    // console.log(response)
    // 因为axios 会在请求返回的结果外层包裹了一个data 所以在响应拦截器中将response.data返回
    const { message, success } = response.data
    if (success) {
      // Message.success(message)
      return response.data
    } else {
      // 当后端返回success 字段false 的时候 需要将promise的状态强制变更拒绝reject
      Message.error(message)
      return Promise.reject(message)
    }
  },
  (error) => {
    // 处理 token 失效
    // 请求失败时（状态码不是 200），触发的回调函数
    // 当后端接口返回 401 状态码时，表示 token 失效，登录过期
    if (error.response.status === 401) {
      // 1. 清除 vuex 中的 token 和用户信息数据，且清除本地的 token
      store.commit('user/removeUserInfo')
      store.commit('settings/resetTheme')
      // 2. 跳转到登录页
      router.push('/login')
      // 3.退出路由 路由重置
      resetRouter()
    }
    return Promise.reject(error)
  }
)

export default request
